extends RigidBody2D

signal chest_opened(chest_id)
signal item_collected(item_id)

@export var chest_id: String = ""  # 宝箱的唯一ID，用于存档
@export var loot_table: Dictionary = {
	"health": 20,   # 20% 概率获得生命
	"sword": 10     # 10% 概率获得剑升级
}
@export var min_coins: int = 5    # 最小金币数量
@export var max_coins: int = 20   # 最大金币数量
@export var always_coins: bool = true  # 是否总是掉落金币

# 金币弹出设置
@export_group("金币弹出设置")
@export var coin_min_force: float = 100.0  # 金币弹出的最小力度
@export var coin_max_force: float = 200.0  # 金币弹出的最大力度
@export var coin_vertical_boost: float = 100.0  # 金币向上的额外推力

@export_group("音效设置")
@export var open_sound: AudioStream
@export var coin_sound: AudioStream

# 预加载物品场景 - 这些资源需要先创建
var coin_scene = null
var health_potion_scene = null 
var sword_upgrade_scene = null
var is_open: bool = false
var player_in_range: bool = false
var player_ref: Node2D = null

# 用于保存状态的字典
var save_properties = ["chest_id", "is_open"]

func _ready():
	# 设置刚体属性
	freeze_mode = RigidBody2D.FREEZE_MODE_KINEMATIC
	
	# 设置音效
	if open_sound:
		$OpenSound.stream = open_sound
	
	# 尝试加载物品场景
	_load_item_scenes()
	
	# 检查是否已经从存档加载了状态
	# 如果游戏已有SaveManager则取消注释下面的代码
	# if has_node("/root/SaveManager"):
	# 	var SaveManager = get_node("/root/SaveManager")
	# 	if SaveManager.has_method("is_item_collected"):
	# 		is_open = SaveManager.is_item_collected(chest_id)
	
	# 如果宝箱已经打开，显示开启状态
	if is_open:
		$AnimatedSprite2D.animation = "opened"
	else:
		$AnimatedSprite2D.animation = "closed"
	
	# 调试信息
	print("宝箱初始化完成，ID:", chest_id)
	print("刚体宝箱 - 质量:", mass, ", 重力缩放:", gravity_scale)
	print("碰撞层设置 - collision_layer:", collision_layer, ", collision_mask:", collision_mask)
	print("交互区域设置 - collision_layer:", $InteractionArea.collision_layer, ", collision_mask:", $InteractionArea.collision_mask)
	print("金币场景加载状态:", "成功" if coin_scene != null else "失败")

# 尝试加载物品场景
func _load_item_scenes():
	print("开始加载物品场景...")
	
	# 尝试使用多种可能的路径加载金币场景
	var possible_coin_paths = [
		"res://scenes/items/coin.tscn",  # 添加到第一位置
		"res://scenes/coin.tscn",
		"res://scenes/items/coin/coin.tscn"
	]
	
	var coin_loaded = false
	for path in possible_coin_paths:
		print("尝试加载金币场景:", path)
		if ResourceLoader.exists(path):
			coin_scene = load(path)
			print("成功加载金币场景:", path)
			coin_loaded = true
			break
	
	if not coin_loaded:
		print("警告: 所有尝试的金币场景路径均不存在，请检查路径")
		
		# 尝试探测items目录内容
		var items_dir = DirAccess.open("res://scenes/items/")
		if items_dir:
			print("items目录存在，内容:")
			items_dir.list_dir_begin()
			var file_name = items_dir.get_next()
			while file_name != "":
				print("- ", file_name)
				file_name = items_dir.get_next()
		else:
			print("items目录不存在或无法访问")
			
		# 尝试探测scenes目录内容
		var scenes_dir = DirAccess.open("res://scenes/")
		if scenes_dir:
			print("scenes目录存在，内容:")
			scenes_dir.list_dir_begin()
			var file_name = scenes_dir.get_next()
			while file_name != "":
				print("- ", file_name)
				file_name = scenes_dir.get_next()
		else:
			print("scenes目录不存在或无法访问")
	
	# 尝试加载生命药水场景
	if ResourceLoader.exists("res://scenes/items/health_potion.tscn"):
		health_potion_scene = load("res://scenes/items/health_potion.tscn")
		print("成功加载生命药水场景")
	else:
		print("警告: 生命药水场景不存在")
	
	# 尝试加载剑升级场景
	if ResourceLoader.exists("res://scenes/items/sword_upgrade.tscn"):
		sword_upgrade_scene = load("res://scenes/items/sword_upgrade.tscn")
		print("成功加载剑升级场景")
	else:
		print("警告: 剑升级场景不存在")

# 物理引擎中的积分步骤处理
func _integrate_forces(state):
	# 在宝箱打开时应用一个轻微的推力，给它一些动态感
	if is_open and state.get_contact_count() > 0:
		# 在有碰撞的情况下，应用小的随机力量
		var impulse = Vector2(randf_range(-10, 10), randf_range(-5, 0))
		state.apply_central_impulse(impulse)

func _process(_delta):
	# 只有当玩家在范围内且宝箱未打开时，显示交互提示
	if player_in_range and not is_open:
		# 如果有UI系统，显示提示
		if get_tree().get_nodes_in_group("ui_interaction_prompt").size() > 0:
			var prompt = get_tree().get_nodes_in_group("ui_interaction_prompt")[0]
			if prompt.has_method("show_prompt"):
				prompt.show_prompt("按 E 打开宝箱")
		else:
			# 如果没有UI系统，直接在控制台显示提示（仅调试用）
			print("按 E 打开宝箱")

func _unhandled_input(event):
	# 调试所有输入事件
	if event is InputEventKey and event.pressed:
		print("按键输入：", event.keycode, " - 玩家在范围内：", player_in_range, " - 宝箱已打开：", is_open)
	
	# 检测玩家的交互输入 (使用unhandled_input，优先级更高)
	if (event.is_action_pressed("interact") or event.is_action_pressed("ui_accept") or 
		(event is InputEventKey and event.keycode == KEY_E and event.pressed)):
		print("检测到交互键！")
		if player_in_range and not is_open:
			print("检测到E键或回车键，尝试打开宝箱")
			open_chest()
			get_viewport().set_input_as_handled()  # 标记输入已处理

func open_chest():
	# 已经打开则忽略
	if is_open:
		return
	
	# 标记为已打开
	is_open = true
	print("打开宝箱！")
	
	# 解冻刚体，让它受物理影响
	freeze = false
	
	# 直接切换到opened动画，不再需要opening动画
	$AnimatedSprite2D.animation = "opened"
	
	# 播放音效
	if $OpenSound.stream:
		$OpenSound.play()
	
	# 激活粒子特效
	$SparkleParticles.emitting = true
	
	# 发送信号
	emit_signal("chest_opened", chest_id)
	
	# 保存宝箱状态
	# 如果游戏已有SaveManager则取消注释下面的代码
	# if has_node("/root/SaveManager"):
	# 	var SaveManager = get_node("/root/SaveManager")
	# 	if SaveManager.has_method("set_item_collected"):
	# 		SaveManager.set_item_collected(chest_id, true)
	
	# 生成物品
	spawn_loot()

func generate_coin_velocity() -> Vector2:
	# 生成随机角度 (-60度到60度之间，正上方为-90度)
	var angle = deg_to_rad(randf_range(-60, 60) - 90)
	
	# 生成随机力度
	var force = randf_range(coin_min_force, coin_max_force)
	
	# 计算速度向量
	var velocity = Vector2(cos(angle), sin(angle)) * force
	
	# 添加额外的向上推力
	velocity.y -= coin_vertical_boost
	
	return velocity

func spawn_loot():
	print("开始生成物品")
	
	# 如果金币场景未加载，再次尝试加载
	if coin_scene == null:
		print("发现金币场景未加载，再次尝试加载...")
		_load_item_scenes()
	
	# 先生成金币（如果设置了always_coins）
	if always_coins:
		_spawn_coins()
	
	# 根据概率表决定是否生成额外物品
	var rand_value = randf() * 100
	var cumulative_chance = 0
	var selected_item = ""
	
	# 从概率表中选择物品
	for item in loot_table:
		cumulative_chance += loot_table[item]
		if rand_value <= cumulative_chance:
			selected_item = item
			break
	
	# 如果没有选择到额外物品或者选到了金币但already_coins为true，则退出
	if selected_item == "" or (selected_item == "coins" and always_coins):
		return
		
	print("选择的额外物品类型: ", selected_item, " 随机值: ", rand_value)
	
	# 根据选择的物品生成对应的场景
	var item_instance = null
	
	match selected_item:
		"health":
			if health_potion_scene:
				item_instance = health_potion_scene.instantiate()
			else:
				print("错误: 生命药水场景未加载")
		
		"sword":
			if sword_upgrade_scene:
				item_instance = sword_upgrade_scene.instantiate()
			else:
				print("错误: 剑升级场景未加载")
	
	# 对非金币物品设置位置和弹出效果
	if item_instance:
		get_tree().current_scene.add_child(item_instance)
		item_instance.global_position = $LootSpawnPosition.global_position
		
		if item_instance.has_method("pop_out"):
			item_instance.pop_out(Vector2(0, -80))

# 生成金币的函数
func _spawn_coins():
	# 确认金币场景已加载
	if coin_scene:
		# 随机生成金币数量
		var coin_count = randi_range(min_coins, max_coins)
		print("生成金币数量: ", coin_count)
		
		# 创建抖动效果
		var tween = create_tween()
		tween.tween_property(self, "position", position + Vector2(0, -3), 0.1)
		tween.tween_property(self, "position", position, 0.1)
		
		print("宝箱抖动中...")
		await tween.finished
		print("宝箱抖动完成")
		
		# 生成金币
		for i in range(coin_count):
			var coin = coin_scene.instantiate()
			if !coin:
				print("错误: 金币实例化失败")
				continue
				
			# 获取当前场景
			var current_scene = get_tree().current_scene
			print("当前场景:", current_scene.name if current_scene else "无")
			
			if current_scene:
				current_scene.add_child(coin)
				print("已添加金币 #", i+1, " 到场景:", current_scene.name)
			else:
				print("错误: 无法获取当前场景")
				# 尝试添加到根节点
				get_tree().root.add_child(coin)
				print("已添加金币到根节点")
			
			# 设置位置，添加一些随机偏移
			var spawn_pos = $LootSpawnPosition.global_position
			coin.global_position = spawn_pos
			print("金币位置: ", coin.global_position)
			
			# 生成随机的弹出速度
			var pop_velocity = generate_coin_velocity()
			print("金币速度: ", pop_velocity)
			
			# 设置金币的弹出效果
			if coin.has_method("pop_out"):
				coin.pop_out(pop_velocity)
				print("已应用弹出效果")
			else:
				print("警告: 金币缺少pop_out方法，可用方法:", coin.get_method_list())
			
			# 短暂延迟，使金币不会同时弹出
			await get_tree().create_timer(0.05).timeout
	else:
		print("错误: 金币场景未加载，coin_scene为空")
		# 手动创建一个简单的金币替代物（应急方案）
		var sprite = Sprite2D.new()
		# 使用动态加载代替preload，使用正确的金币纹理路径
		var coin_texture = null
		var coin_texture_paths = [
			"res://assets/2D Chests & Coins/Coin.png",
			"res://assets/items/coin.png"
		]
		
		# 尝试多个可能的路径
		for path in coin_texture_paths:
			print("尝试加载金币纹理:", path)
			if ResourceLoader.exists(path):
				coin_texture = load(path)
				print("成功加载金币纹理:", path)
				break
		
		sprite.texture = coin_texture
		if sprite.texture:
			get_tree().current_scene.add_child(sprite)
			sprite.global_position = $LootSpawnPosition.global_position
			print("已创建金币替代物")
			
			# 创建动画效果
			var tween = create_tween()
			tween.tween_property(sprite, "scale", Vector2(2.0, 2.0), 0.1)
			tween.tween_property(sprite, "scale", Vector2(1.5, 1.5), 0.2)
		else:
			print("错误: 无法加载金币纹理，尝试过以下路径:", coin_texture_paths)

func _on_interaction_area_body_entered(body):
	# 检查进入区域的是否为玩家
	print("碰撞检测：", body.name, " 组：", body.get_groups())
	if body.is_in_group("player"):
		print("玩家进入宝箱交互区域")
		player_in_range = true
		player_ref = body
	else:
		print("非玩家物体进入交互区域：", body.name)

func _on_interaction_area_body_exited(body):
	# 检查离开区域的是否为玩家
	if body.is_in_group("player"):
		print("玩家离开宝箱交互区域")
		player_in_range = false
		player_ref = null
		
		# 如果有UI系统，隐藏提示
		if get_tree().get_nodes_in_group("ui_interaction_prompt").size() > 0:
			var prompt = get_tree().get_nodes_in_group("ui_interaction_prompt")[0]
			if prompt.has_method("hide_prompt"):
				prompt.hide_prompt() 
